package main

import (
	"bytes"
	"html/template"
	"strings"
)

// 模板用法：https://colobu.com/2019/11/05/Golang-Templates-Cheatsheet/#Range
var tpl = `

type {{$.Name}}HttpServer struct {
	server {{$.Name}}Server
	router gin.IRouter
}

func Register{{$.Name}}ServerHTTPServer(srv {{$.Name}}Server, r gin.IRouter) {
	s := {{$.Name}}HttpServer{
		server: srv,
		router: r,
	}
	s.RegisterService()
}

{{range .Methods}}
func (s *{{$.Name}}HttpServer) {{.HandlerName}}(c *gin.Context) {
	var in {{.Request}}

	if err := c.ShouldBindJSON(&in); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	out, err := s.server.{{.Name}}(c, &in)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, out)
}
{{end}}

func (s *{{$.Name}}HttpServer) RegisterService() {
{{range .Methods}}
	s.router.Handle("{{.Method}}", "{{.Path}}", s.{{.HandlerName}})
{{end}}
}
`

type serviceDesc struct {
	Name    string
	Methods []method
}

type method struct {
	Name    string
	Request string
	Reply   string

	//http rule
	Path   string
	Method string
	Body   string
}

func (m *method) HandlerName() string {
	return m.Name + "_0"
}

func main() {
	//模板
	buf := &bytes.Buffer{}
	tmpl, err := template.New("http").Parse(strings.TrimSpace(tpl))
	if err != nil {
		panic(err)
	}

	s := serviceDesc{
		Name: "Greeter",
		Methods: []method{
			{
				Name:    "SayHello",
				Request: "HelloRequest",
				Reply:   "HelloReply",
				Path:    "/v1/sayhello",
				Method:  "post",
				Body:    "*",
			},
			{
				Name:    "SayHelloAgain",
				Request: "HelloRequest",
				Reply:   "HelloReply",
				Path:    "/v1/sayhelloagain",
				Method:  "post",
				Body:    "*",
			},
		},
	}

	err = tmpl.Execute(buf, s)
	if err != nil {
		panic(err)
	}

	println(buf.String())

}
